/*
 * TowerUpgradeRange.java
 *
 * Created on January 19, 2008, 11:57 AM
 *
 * Copyright (C) 2007-2008  Hylke van der Schaaf
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, in version 3 of the License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package hextd.tower;

import hextd.Constants;
import hextd.hex.HexTile;
import hextd.util.Cache;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.usoog.tdcore.exception.TileAlreadyHasTowerException;
import com.usoog.tdcore.exception.TileNotBuildableException;
import com.usoog.tdcore.player.Player;
import com.usoog.tdcore.tower.TowerListener;
import hextd.core.GameStateImplementation;

/**
 *
 * @author hylke
 */
public class TowerUpgradeRange extends TowerBase implements TowerListener<HexTDTower> {

	public static final Map<String, Long> price = new HashMap<String, Long>();

	static {
		price.put(Constants.RESOURCE_BONUS, 1l);
	}
	public static int damage = 0;
	public static double range = 4.3f;
	public static String name = "Range Assist";
	//
	private List<HexTDTower> clients;
	private Line2D[] clientLines;
	private Stroke clientStroke;
	private Color clientColor;
	public static double upgradeEffectRange = 0.5f;
	private Point2D.Double tempTowerGLoc = new Point2D.Double();
	private Point2D.Double tempTargetPLoc = new Point2D.Double();

	/** Creates a new instance of TowerUpgradeRange */
	public TowerUpgradeRange() {
		super(FactoryTower.type.upgradeRange, price, damage, range);

		hexInfluence = 1;
		lineColor = new Color(200, 200, 200);
		clientColor = new Color(50, 255, 50);
		clients = new ArrayList<HexTDTower>();
		pts = null;
	}

	@Override
	public void init(
			GameStateImplementation gs,
			HexTile hex,
			Player owner,
			int activateTick)
			throws TileAlreadyHasTowerException, TileNotBuildableException {
		super.init(gs, hex, owner, activateTick);
		gameState.addTowerListener(this);
		scanTowers();
	}

	@Override
	protected boolean runActivate() {
		if (super.runActivate()) {
			scanTowers();
			return true;
		} else {
			return false;
		}
	}

	private void scanTowers() {
		if (!selling && active) {
			HexTDTower t;
			double dx, dy;
			double[] loc;
			for (Iterator<HexTDTower> i = gameState.getTowers().iterator(); i.hasNext();) {
				t = i.next();
				t.getTile().getGameLocation(tempTowerGLoc);
				dx = gameLocation.x - tempTowerGLoc.x;
				dy = gameLocation.y - tempTowerGLoc.y;
				if (!clients.contains(t) && t.getOwner() == getOwner()) {
					if ((dx * dx + dy * dy) < rangeCurrent2) {
						t.registerTower(this);
					}
				} else {
					if (clients.contains(t) && (dx * dx + dy * dy) > rangeCurrent2) {
						t.unregisterTower(this);
					}
				}
			}
		}
	}

	@Override
	protected void calcDamageRange() {
		super.calcDamageRange();
		scanTowers();
	}

	@Override
	public boolean canUpgrade(String mode, boolean afterQueue) {
		return false;
	}

	@Override
	public String getStatusString() {
		String retString = "";
		retString += "<h1>Range Upgrade</h1>"
				+ "<p>"
				+ "Increases the range of other towers, including other upgrade towers.<br>"
				+ "<b>Towers affected:</b> " + clients.size() + "<br>\n"
				+ "<b>Range:</b> " + rangeText + "<br>"
				+ "</p>\n";
		return retString;
	}

	@Override
	public String getDescription() {
		String retString = "";
		retString += "<h1>Range Upgrade</h1>"
				+ "<p>Increases the range of other towers by " + upgradeEffectRange + ".</p>"
				+ "<p class='warn'>This tower costs 1 bonus point.</p>";
		return retString;
	}

	@Override
	public void runTick(int gameTime) {
	}

	@Override
	public void towerAdded(HexTDTower t) {
		if (t != this && !selling && !clients.contains(t) && t.getOwner() == getOwner()) {
			double dx, dy;
			t.getTile().getGameLocation(tempTowerGLoc);
			dx = gameLocation.x - tempTowerGLoc.x;
			dy = gameLocation.y - tempTowerGLoc.y;
			if ((dx * dx + dy * dy) < rangeCurrent2) {
				t.registerTower(this);
			}
		}
	}

	@Override
	public void towerRemoved(HexTDTower t) {
		if (clients.contains(t)) {
			t.unregisterTower(this);
		}
	}

	public void addClient(HexTDTower t) {
		if (!selling && !clients.contains(t)) {
			clients.add(t);
			generateShapes();
		}
	}

	public void removeClient(HexTDTower t) {
		clients.remove(t);
		generateShapes();
	}

	@Override
	public void delete() {
		super.delete();
		for (int i = clients.size() - 1; i >= 0; i--) {
			HexTDTower t = clients.get(i);
			t.unregisterTower(this);
		}
		gameState.removeTowerListener(this);
	}

	@Override
	public String getSvgName() {
		return "upgradeRange";
	}

	@Override
	protected void generateShapes() {
		Cache.getInstance().loadSvg("upgradeRange", "images/upgradeRange.svg");
		double cx = +0;
		double cy = +0;

		shapes = new Shape[0];

		clientLines = new Line2D[clients.size()];
		Point2D.Double from = new Point2D.Double();
		Point2D.Double to = new Point2D.Double(paintLocation.x + cx, paintLocation.y + cy);
		for (int i = 0; i < clientLines.length; i++) {
			from = clients.get(i).getTile().getPaintLocation(from);
			clientLines[i] = new Line2D.Double(from.x, from.y, to.x, to.y);
		}
		clientStroke = new BasicStroke(1.0f * strokeScale, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
	}

	@Override
	public void paintEffects(Graphics2D g2, int gameTime) {
		if (selected) {
			g2.setStroke(clientStroke);
			g2.setColor(clientColor);
			for (int i = 0; i < clientLines.length; i++) {
				g2.draw(clientLines[i]);
			}
		}
	}
}
